package com.lxm.framework.auth.filter;

import com.lxm.framework.auth.model.AuthFilterRegister;
import com.lxm.framework.auth.router.LxmRouterUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: Lys
 * @Date 2023/5/30
 * @Describe
 **/
@Slf4j
@Component
public class LxmServletFilter implements Filter {

    /**
     * 拦截路由
     */
    private List<String> includeList = new ArrayList<>();

    /**
     * 放行路由
     */
    private List<String> excludeList = new ArrayList<>();

    private ServletFilterStrategy auth;

    private ServletErrorStrategy error;

    @Autowired(required = false)
    public LxmServletFilter(AuthFilterRegister filterConfig) {
        this.setIncludeList(filterConfig.includes());
        this.setExcludeList(filterConfig.excludes());
        this.setAuth(filterConfig.whenBlocked());
        this.setError(filterConfig.whenError());
        log.debug("lxm-auth servlet filter initialized success");
    }

    /**
     * 添加 [拦截路由]
     *
     * @param paths 路由
     * @return 对象自身
     */
    public LxmServletFilter addInclude(String... paths) {
        includeList.addAll(Arrays.asList(paths));
        return this;
    }

    /**
     * 添加 [放行路由]
     *
     * @param paths 路由
     * @return 对象自身
     */
    public LxmServletFilter addExclude(String... paths) {
        excludeList.addAll(Arrays.asList(paths));
        return this;
    }

    /**
     * 写入 [拦截路由] 集合
     *
     * @param pathList 路由集合
     * @return 对象自身
     */
    public LxmServletFilter setIncludeList(List<String> pathList) {
        includeList = pathList;
        return this;
    }

    /**
     * 写入 [放行路由] 集合
     *
     * @param pathList 路由集合
     * @return 对象自身
     */
    public LxmServletFilter setExcludeList(List<String> pathList) {
        excludeList = pathList;
        return this;
    }


    /**
     * 获取 [拦截路由] 集合
     *
     * @return see note
     */
    public List<String> getIncludeList() {
        return includeList;
    }

    /**
     * 获取 [放行路由] 集合
     *
     * @return see note
     */
    public List<String> getExcludeList() {
        return excludeList;
    }

    public LxmServletFilter setAuth(ServletFilterStrategy strategy) {
        this.auth = strategy;
        return this;
    }

    public LxmServletFilter setError(ServletErrorStrategy error) {
        this.error = error;
        return this;
    }


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            // 执行全局过滤器
            LxmRouterUtil.match(includeList, excludeList, () -> auth.run());
        } catch (Throwable e) {
            // 1. 获取异常处理策略结果
            Object result = error.run(e);
            String resultString = String.valueOf(result);
            // 2. 写入输出流
            try {
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().print(resultString);
            } catch (Exception ee) {
                ee.printStackTrace();
            }
            return;
        }
        // 执行
        chain.doFilter(request, response);
    }

}
